Carga de datos
## Warning: package 'readr' was built under R version 4.4.3
## Warning: package 'dplyr' was built under R version 4.4.3
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# Cargar los archivos
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", show_col_types = FALSE)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", show_col_types = FALSE)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", show_col_types = FALSE)
# Unir todos en un solo data frame
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Revisar estructura
glimpse(df)
## Rows: 1,671,036
## Columns: 18
## $ folio <chr> "C5/20220110/02402", "C5/20220129/01383", "C5/2…
## $ categoria_incidente_c4 <chr> "Medicos", "Derrame o fuga", "Cadaver", "Cadave…
## $ incidente_c4 <chr> "Dolor", "Olor a gas combustible quimicos", "Mu…
## $ anio_creacion <dbl> 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022,…
## $ mes_creacion <chr> "Enero", "Enero", "Enero", "Enero", "Enero", "E…
## $ fecha_creacion <date> 2022-01-10, 2022-01-29, 2022-01-29, 2022-01-29…
## $ hora_creacion <time> 17:01:37, 10:39:06, 16:28:36, 15:28:21, 14:33:…
## $ anio_cierre <dbl> 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022,…
## $ mes_cierre <chr> "Enero", "Enero", "Enero", "Enero", "Enero", "E…
## $ fecha_cierre <date> 2022-01-10, 2022-01-29, 2022-01-29, 2022-01-29…
## $ hora_cierre <time> 20:04:48, 13:46:10, 21:16:09, 19:26:09, 20:36:…
## $ codigo_cierre <chr> "Otros", "Otros", "A", "A", "A", "A", "A", "A",…
## $ clas_con_f_alarma <chr> "URGENCIAS MEDICAS", "EMERGENCIA", "EMERGENCIA"…
## $ alcaldia_cierre <chr> "IZTAPALAPA", "IZTACALCO", "IZTAPALAPA", "IZTAP…
## $ colonia_cierre <chr> "LOS ANGELES", "REFORMA IZTACCIHUATL NORTE", "E…
## $ manzana <chr> "9.01E+14", "9.01E+14", "9.01E+14", "9.01E+14",…
## $ latitud <dbl> 19.34255, 19.38376, 19.35514, 19.37824, 19.4334…
## $ longitud <dbl> -99.06475, -99.12516, -99.09455, -99.09951, -99…
y calcula el número promedio de incidentes por categoría.
library(dplyr)
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
# Agrupar por mes y alcaldía
df %>%
count(mes_creacion, alcaldia_cierre) %>%
mutate(
mes_creacion = factor(mes_creacion,
levels = c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"),
ordered = TRUE)
) %>%
ggplot(aes(x = mes_creacion, y = n, fill = alcaldia_cierre)) +
geom_col(position = "dodge") +
labs(
title = "Número de incidentes por mes y alcaldía",
x = "Mes",
y = "Número de incidentes",
fill = "Alcaldía"
) +
theme_minimal(base_size = 14) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

# extraemos las categorias
library(dplyr)
library(readr)
# Cargar tus datasets
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", show_col_types = FALSE)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", show_col_types = FALSE)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", show_col_types = FALSE)
# Unir los tres en un solo dataframe
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Contar categorías únicas y ordenarlas por frecuencia
categorias <- df %>%
filter(!is.na(categoria_incidente_c4)) %>%
count(categoria_incidente_c4, sort = TRUE)
# Ver resultado
print(categorias, n = Inf)
## # A tibble: 23 × 2
## categoria_incidente_c4 n
## <chr> <int>
## 1 Disturbio 291628
## 2 Servicios 271150
## 3 Agresion 172348
## 4 Administrativas 161069
## 5 Denuncia 133330
## 6 Medicos 126229
## 7 Lesionado 72815
## 8 Derrame o fuga 59808
## 9 Incendio 53509
## 10 Danos por fenomeno natural o tercero 23092
## 11 Danos 15275
## 12 Abandono 14983
## 13 Robo 11316
## 14 Cadaver 9439
## 15 Contra la salud 6383
## 16 Amenaza 6353
## 17 Explosion 3461
## 18 Detencion ciudadana 3422
## 19 Privacion de la libertad 3011
## 20 Intento de suicidio 2658
## 21 Sismo 2384
## 22 Accidente 81
## 23 Persona extraviada en zona boscosa 80
library(dplyr)
library(ggplot2)
library(readr)
# Cargar datasets
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", show_col_types = FALSE)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", show_col_types = FALSE)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", show_col_types = FALSE)
# Unir los tres datasets
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Contar y ordenar categorías
categorias <- df %>%
filter(!is.na(categoria_incidente_c4)) %>%
count(categoria_incidente_c4, sort = TRUE)
# Gráfico de barras
ggplot(categorias, aes(x = reorder(categoria_incidente_c4, n), y = n)) +
geom_col(fill = "#0073C2FF") +
coord_flip() +
labs(
title = "Frecuencia de categorías de incidentes 911",
x = "Categoría",
y = "Número de incidentes"
) +
theme_minimal(base_size = 14)

library(dplyr)
library(ggplot2)
library(readr)
# Cargar datasets
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", show_col_types = FALSE)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", show_col_types = FALSE)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", show_col_types = FALSE)
# Unir los tres datasets
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Contar y ordenar categorías
categorias <- df %>%
filter(!is.na(categoria_incidente_c4)) %>%
count(categoria_incidente_c4, sort = TRUE)
# Gráfico de barras con etiquetas
ggplot(categorias, aes(x = reorder(categoria_incidente_c4, n), y = n)) +
geom_col(fill = "#0073C2FF") +
geom_text(aes(label = n), hjust = -0.1, size = 3.5) + # Agrega los totales
coord_flip() +
labs(
title = "Frecuencia de categorías de incidentes 911",
x = "Categoría",
y = "Número de incidentes"
) +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(hjust = 0.5)) +
expand_limits(y = max(categorias$n) * 1.05) # Espacio para que no se corte el número

library(dplyr)
library(ggplot2)
library(readr)
# Cargar datasets con columna año
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", show_col_types = FALSE) %>% mutate(anio = 2022)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", show_col_types = FALSE) %>% mutate(anio = 2021)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", show_col_types = FALSE) %>% mutate(anio = 2021)
# Unir los datasets
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Contar categorías por año
categorias_anio <- df %>%
filter(!is.na(categoria_incidente_c4)) %>%
count(anio, categoria_incidente_c4)
# Para controlar el orden de las categorías (por total combinado)
orden_categorias <- categorias_anio %>%
group_by(categoria_incidente_c4) %>%
summarise(total = sum(n)) %>%
arrange(total) %>%
pull(categoria_incidente_c4)
categorias_anio$categoria_incidente_c4 <- factor(categorias_anio$categoria_incidente_c4, levels = orden_categorias)
# Crear gráfico barras agrupadas por año
ggplot(categorias_anio, aes(x = categoria_incidente_c4, y = n, fill = factor(anio))) +
geom_col(position = "dodge") +
geom_text(aes(label = n), position = position_dodge(width = 0.9), vjust = -0.5, size = 3) +
scale_fill_manual(values = c("2020" = "green", "2021" = "blue", "2022" = "red")) +
coord_flip() +
labs(
title = "Frecuencia de categorías de incidentes 911 por año",
x = "Categoría",
y = "Número de incidentes",
fill = "Año"
) +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(hjust = 0.5))

2. Identifica el día de la semana con más incidentes y determinar el
total de llamadas para ese día.
library(dplyr)
library(ggplot2)
library(readr)
# Cargar datasets
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", show_col_types = FALSE)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", show_col_types = FALSE)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", show_col_types = FALSE)
# Unir datasets
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Agrupar por año y categoría, excluir NA
df_heatmap <- df %>%
filter(!is.na(categoria_incidente_c4), !is.na(anio_creacion)) %>%
count(anio_creacion, categoria_incidente_c4)
# Gráfico heatmap con números y escala roja
ggplot(df_heatmap, aes(x = factor(anio_creacion), y = reorder(categoria_incidente_c4, -n), fill = n)) +
geom_tile(color = "white") +
geom_text(aes(label = n), color = "black", size = 3) + # Añadir números
scale_fill_gradient(low = "#fee0d2", high = "#de2d26", name = "Incidentes") +
labs(
title = "Heatmap de categorías de incidentes por año",
x = "Año",
y = "Categoría"
) +
theme_minimal(base_size = 14) +
theme(axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 10))

library(dplyr)
library(ggplot2)
library(readr)
library(lubridate)
## Warning: package 'lubridate' was built under R version 4.4.3
##
## Adjuntando el paquete: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
# Cargar datasets
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", show_col_types = FALSE)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", show_col_types = FALSE)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", show_col_types = FALSE)
# Unir datasets
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Procesar: obtener día de la semana
df_dias <- df %>%
filter(!is.na(fecha_creacion), !is.na(anio_creacion)) %>%
mutate(dia_semana = wday(fecha_creacion, label = TRUE, abbr = FALSE, week_start = 1)) %>% # lunes a domingo
count(anio_creacion, dia_semana)
# Gráfico de líneas con números
ggplot(df_dias, aes(x = dia_semana, y = n, color = factor(anio_creacion), group = anio_creacion)) +
geom_line(size = 1.2) +
geom_point(size = 3) +
geom_text(aes(label = n), vjust = -0.5, size = 4) +
labs(
title = "Número de incidentes por día de la semana y por año",
x = "Día de la semana",
y = "Número de incidentes",
color = "Año"
) +
theme_minimal(base_size = 14) +
theme(axis.text.x = element_text(size = 12))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

4. Calcula el tiempo promedio entre la creación y cierre del
incidente (usa fecha_creacion y fecha_cierre). Así mismo, determinar el
tiempo mínimo y máximo.
library(readr)
library(dplyr)
library(lubridate)
# Unir datasets con su año
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", locale = locale(encoding = "UTF-8"), show_col_types = FALSE)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", locale = locale(encoding = "UTF-8"), show_col_types = FALSE)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", locale = locale(encoding = "UTF-8"), show_col_types = FALSE)
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Limpiar strings y convertir fecha y hora
df <- df %>%
mutate(
fecha_creacion = trimws(fecha_creacion),
hora_creacion = trimws(hora_creacion),
fecha_cierre = trimws(fecha_cierre),
hora_cierre = trimws(hora_cierre),
fecha_hora_creacion = ymd(fecha_creacion) + hms(hora_creacion),
fecha_hora_cierre = ymd(fecha_cierre) + hms(hora_cierre),
duracion_minutos = as.numeric(difftime(fecha_hora_cierre, fecha_hora_creacion, units = "mins"))
)
# Verificar que las fechas están bien convertidas
df %>% select(fecha_creacion, hora_creacion, fecha_hora_creacion) %>% head()
# Calcular estadísticas
resumen <- df %>%
summarise(
promedio_min = mean(duracion_minutos, na.rm = TRUE),
minimo_min = min(duracion_minutos, na.rm = TRUE),
maximo_min = max(duracion_minutos, na.rm = TRUE)
)
print(resumen)
## # A tibble: 1 × 3
## promedio_min minimo_min maximo_min
## <dbl> <dbl> <dbl>
## 1 166. -55.9 1086041.
library(readr)
library(dplyr)
library(lubridate)
# Unir datasets con su año
df_1_2022 <- read_csv("llamadas_911_2022_s1.csv", locale = locale(encoding = "UTF-8"), show_col_types = FALSE)
df_2_2021 <- read_csv("llamadas_911_2021_s2.csv", locale = locale(encoding = "UTF-8"), show_col_types = FALSE)
df_1_2021 <- read_csv("llamadas_911_2021_s1.csv", locale = locale(encoding = "UTF-8"), show_col_types = FALSE)
df <- bind_rows(df_1_2022, df_2_2021, df_1_2021)
# Limpiar strings y convertir fecha y hora
df <- df %>%
mutate(
fecha_creacion = trimws(fecha_creacion),
hora_creacion = trimws(hora_creacion),
fecha_cierre = trimws(fecha_cierre),
hora_cierre = trimws(hora_cierre),
fecha_hora_creacion = ymd(fecha_creacion) + hms(hora_creacion),
fecha_hora_cierre = ymd(fecha_cierre) + hms(hora_cierre),
duracion_minutos = as.numeric(difftime(fecha_hora_cierre, fecha_hora_creacion, units = "mins"))
)
# Verificar que las fechas están bien convertidas
df %>%
select(fecha_creacion, hora_creacion, fecha_hora_creacion) %>%
head()
# Calcular promedio de duración por categoría
promedio_por_categoria <- df %>%
filter(!is.na(duracion_minutos), !is.na(categoria_incidente_c4)) %>%
group_by(categoria_incidente_c4) %>%
summarise(promedio_duracion_min = mean(duracion_minutos, na.rm = TRUE),cantidad_incidentes = n()) %>%
arrange(desc(promedio_duracion_min)) # Opcional: ordenar por duración
# Mostrar resultado
print(promedio_por_categoria)
## # A tibble: 23 × 3
## categoria_incidente_c4 promedio_duracion_min cantidad_incidentes
## <chr> <dbl> <int>
## 1 Sismo 2651. 2384
## 2 Denuncia 519. 133330
## 3 Cadaver 335. 9439
## 4 Accidente 240. 81
## 5 Intento de suicidio 224. 2658
## 6 Persona extraviada en zona boscosa 220. 80
## 7 Servicios 216. 271150
## 8 Derrame o fuga 200. 59808
## 9 Danos por fenomeno natural o terce… 194. 23092
## 10 Abandono 175. 14983
## # ℹ 13 more rows
df_por_anio <- df %>%
filter(!is.na(duracion_minutos), !is.na(categoria_incidente_c4)) %>%
mutate(anio = year(fecha_hora_creacion)) %>% group_by(anio, categoria_incidente_c4) %>% summarise(promedio_duracion_min = mean(duracion_minutos, na.rm = TRUE),.groups = "drop")
# Gráfico
ggplot(df_por_anio, aes(x = reorder(categoria_incidente_c4, promedio_duracion_min), y = promedio_duracion_min, fill = factor(anio))) +
geom_col(position = "dodge") +
coord_flip() +
labs(
title = "Duración promedio por categoría y año",
x = "Categoría",
y = "Duración promedio (minutos)",
fill = "Año"
) +
theme_minimal(base_size = 14)

5. Determinar el porcentaje de llamadas que fueron clasificadas como
“Falsa Alarma”.
# Calcular porcentaje de "Falsa Alarma"
porcentaje_falsa_alarma <- df %>%
filter(!is.na(clas_con_f_alarma)) %>%
mutate(falsa_alarma = clas_con_f_alarma == "FALSA ALARMA") %>%
summarise(
total_llamadas = n(),
total_falsas = sum(falsa_alarma),
porcentaje = total_falsas / total_llamadas * 100
)
print(porcentaje_falsa_alarma)
## # A tibble: 1 × 3
## total_llamadas total_falsas porcentaje
## <int> <int> <dbl>
## 1 1671036 504 0.0302
df_falsa <- df %>%
filter(!is.na(clas_con_f_alarma)) %>%
mutate(clasificacion = ifelse(clas_con_f_alarma == "FALSA ALARMA", "FALSA ALARMA", "Otra")) %>%
count(clasificacion) %>%
mutate(porcentaje = n / sum(n) * 100)
ggplot(df_falsa, aes(x = "", y = porcentaje, fill = clasificacion)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
geom_text(aes(label = paste0(round(porcentaje, 1), "%")),
position = position_stack(vjust = 0.5),
color = "white", size = 4) +
labs(
title = "Porcentaje de llamadas clasificadas como Falsa Alarma",
fill = "Clasificación"
) +
theme_void()

df_falsa <- df %>%
filter(!is.na(clas_con_f_alarma)) %>%
mutate(clasificacion = ifelse(clas_con_f_alarma == "FALSA ALARMA", "FALSA ALARMA", "Otra")) %>%
count(clasificacion) %>%
mutate(porcentaje = n / sum(n) * 100)
ggplot(df_falsa, aes(x = "", y = porcentaje, fill = clasificacion)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
geom_text(
aes(label = paste0(sprintf("%.3f", porcentaje), "%")),
position = position_stack(vjust = 0.5),
color = "white", size = 4
) +
labs(
title = "Porcentaje de llamadas clasificadas como Falsa Alarma",
fill = "Clasificación"
) +
theme_void()

library(ggplot2)
library(dplyr)
library(lubridate)
# Asegurarse de que `fecha_hora_creacion` esté correctamente generado
df <- df %>%
mutate(
fecha_hora_creacion = ymd(fecha_creacion) + hms(hora_creacion),
anio = year(fecha_hora_creacion)
)
# Función para graficar por año
graficar_falsa_alarma <- function(df, anio_target) {
df_falsa <- df %>%
filter(!is.na(clas_con_f_alarma), anio == anio_target) %>%
mutate(clasificacion = ifelse(clas_con_f_alarma == "FALSA ALARMA", "FALSA ALARMA", "Otra")) %>%
count(clasificacion) %>%
mutate(porcentaje = n / sum(n) * 100)
ggplot(df_falsa, aes(x = "", y = porcentaje, fill = clasificacion)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
geom_text(
aes(label = paste0(sprintf("%.3f", porcentaje), "%")),
position = position_stack(vjust = 0.5),
color = "white", size = 4
) +
labs(
title = paste("Porcentaje Falsa Alarma -", anio_target),
fill = "Clasificación"
) +
theme_void()
}
# Graficar por año
grafico_2020 <- graficar_falsa_alarma(df, 2020)
grafico_2021 <- graficar_falsa_alarma(df, 2021)
grafico_2022 <- graficar_falsa_alarma(df, 2022)
# Mostrar gráficos (en RStudio, uno por uno o con patchwork/cowplot/gridExtra)
print(grafico_2020)


